package com.huawo.opensdk.manager;


import static com.huawo.opensdk.ApplicationHolder.sApplication;
import static com.sifli.siflidfu.Protocol.DFU_MODE_NORMAL;
import static com.sifli.siflidfu.Protocol.IMAGE_ID_CTRL;
import static com.sifli.siflidfu.Protocol.IMAGE_ID_DYN;
import static com.sifli.siflidfu.Protocol.IMAGE_ID_HCPU;
import static com.sifli.siflidfu.Protocol.IMAGE_ID_LCPU;
import static com.sifli.siflidfu.Protocol.IMAGE_ID_NAND_LCPU_PATCH;
import static com.sifli.siflidfu.Protocol.IMAGE_ID_NAND_RES;
import static com.sifli.siflidfu.Protocol.IMAGE_ID_RES;

import android.annotation.SuppressLint;
import android.text.TextUtils;
import android.util.Log;

import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;

import com.huawo.opensdk.bean.DeviceUpgradeInfo;
import com.huawo.opensdk.utils.MD5Utils;
import com.huawo.opensdk.utils.SM;
import com.huawo.opensdk.utils.UploadFileUtils;
import com.sifli.siflidfu.DFUImagePath;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import io.reactivex.Observable;
import io.reactivex.Single;
import io.reactivex.schedulers.Schedulers;
import kotlin.io.FilesKt;
import com.sifli.siflidfu.SifliDFUService;
@SuppressLint("CheckResult")
public class DeviceUpgradeManager {

    private static final String JSON_KEY_LAST_CHECK_UPGRADE_INFO_TIME = "lastCheckUpgradeInfoTime";
    public static final MutableLiveData<Boolean> qjsDownZipState = new MutableLiveData<>();

    private static final String JSON_KEY_DEVICE_UPGRADE_INFO = "deviceUpgradeInfo";
    public static final String HAS_WAITING_UPGRADE = "has_waiting_upgrade";//是否执行过强制更新的逻辑,就不弹出了
    private static DeviceUpgradeInfo deviceUpgradeInfo;
    private static final MutableLiveData<DeviceUpgradeInfo> deviceUpgradeInfoMutableLiveData = new MutableLiveData<>();
//    private static final SingleLiveEvent<Boolean> autoUpgradeMutableLiveData = new SingleLiveEvent<>();

    public static DeviceUpgradeInfo getDeviceUpgradeInfo() {
        return deviceUpgradeInfo;
    }

    public static DeviceUpgradeInfo.Resource localResource;

    public static LiveData<DeviceUpgradeInfo> getDeviceUpgradeInfoLiveData() {
        return deviceUpgradeInfoMutableLiveData;
    }

//    public static LiveData<Boolean> getAutoUpgradeLiveData() {
//        return autoUpgradeMutableLiveData;
//    }

//    public static void setAutoUpgradeMutableLiveData(Boolean autoUpgrade) {
//        autoUpgradeMutableLiveData.postValue(autoUpgrade);
//    }

    public static void setDeviceUpgradeInfo(DeviceUpgradeInfo deviceUpgradeInfo) {
        try {
            Log.i("DeviceUpgradeManager", "【OTA - 检查更新】设置更新状态：" + deviceUpgradeInfo);
            DeviceUpgradeManager.deviceUpgradeInfo = deviceUpgradeInfo;
            deviceUpgradeInfoMutableLiveData.postValue(deviceUpgradeInfo);
            Log.i("DeviceUpgradeManager", "【OTA - 检查更新】设置更新状态 -> 成功");
        } catch (Exception e) {
            Log.e("DeviceUpgradeManager", "【OTA - 检查更新】设置更新状态 -> 失败", e);
//            throw e;
        }
    }

//    public static Completable checkAutoUpgradeInfo() {
//        return Completable.create(emitter -> {
//            try {
//                final ConnectDevice connectDevice = DeviceConnectManager.getConnectDevice();
//                if (connectDevice != null) {
//                               Log.i("DeviceUpgradeManager","【OTA - 检查自动更新】 开始");
//                    DeviceSDKProxy.getBindStateAutoUpgrade().timeout(30, TimeUnit.SECONDS)
//                            .observeOn(AndroidSchedulers.mainThread())
//                            .subscribe(autoUpgrade -> {
//                                           Log.i("DeviceUpgradeManager","【OTA - 检查自动更新】 查询状态成功 " + autoUpgrade);
//                                if (autoUpgrade) {
//                                    setAutoUpgradeMutableLiveData(true);
//                                               Log.i("DeviceUpgradeManager","【OTA - 检查自动更新】 查询状态成功 需要自动更新");
//                                } else {
//                                               Log.i("DeviceUpgradeManager","【OTA - 检查自动更新】 查询状态成功 不用自动更新");
//                                }
//                                emitter.onComplete();
//                            }, emitter::onError);
//                } else {
//                               Log.i("DeviceUpgradeManager","【OTA - 检查自动更新】 设备未连接");
//                    emitter.onComplete();
//                }
//            } catch (Exception e) {
//                           Log.i("DeviceUpgradeManager","【OTA - 检查自动更新】 失败", e);
//                emitter.onError(e);
//            }
//        }).subscribeOn(Schedulers.io());
//    }

//    public static Observable<Boolean> checkAutoUpgradeInfo_new() {
//        return Observable.interval(0, 30, TimeUnit.SECONDS)
//                .flatMap(ignore -> {
//                    try {
//                        final ConnectDevice connectDevice = DeviceConnectManager.getConnectDevice();
//                        if (connectDevice != null) {
//                                       Log.i("DeviceUpgradeManager","【OTA - 检查自动更新】 开始");
//                            return DeviceSDKProxy.getBindStateAutoUpgrade()
//                                    .observeOn(AndroidSchedulers.mainThread())
//                                    .doOnSuccess(autoUpgrade -> {
//                                        if (autoUpgrade) {
//                                                       Log.i("DeviceUpgradeManager","【OTA - 检查自动更新】 查询状态成功 需要自动更新");
//                                        } else {
//                                                       Log.i("DeviceUpgradeManager","【OTA - 检查自动更新】 查询状态成功 不用自动更新");
//                                        }
//                                    })
//                                    .toObservable();
//                        } else {
//                                       Log.i("DeviceUpgradeManager","【OTA - 检查自动更新】 设备未连接");
//                            return Observable.just(false);
//                        }
//                    } catch (Exception e) {
//                                   Log.i("DeviceUpgradeManager","【OTA - 检查自动更新】 失败", e);
//                        return Observable.error(e);
//                    }
//                })
//                .distinctUntilChanged()
//                .subscribeOn(Schedulers.io());
//    }

//    public static Completable checkUpgradeInfo() {
//        return Completable.create(emitter -> {
//            try {
//                try {
//
//                    ConnectivityManager connectivityManager = (ConnectivityManager) sApplication.getSystemService(Context.CONNECTIVITY_SERVICE);
//                    if (connectivityManager.getActiveNetworkInfo().isConnected()) {
//                        Log.i("DeviceUpgradeManager","【OTA - 检查更新】==no network reset deviceUpgradeInfoJson==");
//                        emitter.onError(new NetworkErrorException());
//                    }
//
//                    final ConnectDevice connectDevice = DeviceConnectManager.getConnectDevice();
//                    if (connectDevice != null) {
//
//                           Log.i("DeviceUpgradeManager","【OTA - 检查更新】开始...");
//                            String currentFirmwareVersion = FirmwareVersionUtils.extractV(connectDevice.firmwareVersion);
//                            Long currentBuildCode = FirmwareVersionUtils.extractB(connectDevice.firmwareVersion);
//                            if (currentFirmwareVersion != null) {
//                                Map<String, Object> requestBody = DeviceRemote.upgradesRequestBody(
//                                        currentFirmwareVersion,
//                                        connectDevice.deviceType,
//                                        currentBuildCode);
//                                           Log.i("DeviceUpgradeManager","【OTA - 检查更新】服务器接口请求参数：" + requestBody);
//                                RemoteResponse<DeviceUpgradeInfo> remoteResponse = RetrofitClient.retrofit().create(DeviceRemote.class)
//                                        .upgrades(requestBody)
//                                        .blockingGet();
//                                           Log.i("DeviceUpgradeManager","【OTA - 检查更新】服务器接口响应：" + remoteResponse);
//                                if (!remoteResponse.isOk()) {
//                                    throw new RemoteResponseException(remoteResponse);
//                                }
//                                DeviceUpgradeInfo deviceUpgradeInfo = remoteResponse.getData();
//                                           Log.i("DeviceUpgradeManager","【OTA - 检查更新】服务器接口响应解析结果：" + deviceUpgradeInfo);
//                                localResource = deviceUpgradeInfo.resource;
//                            }else{
//                                           Log.i("DeviceUpgradeManager","【OTA - 检查更新】version error=retry=DeviceUpgradeManager");
//                                Observable.timer(2000, TimeUnit.MILLISECONDS)
//                                        .subscribeOn(Schedulers.io())
//                                        .flatMapSingle(a -> DeviceManager.getConnectDevice()
//                                                .timeout(30, TimeUnit.SECONDS, Schedulers.io()))
//                                        .observeOn(AndroidSchedulers.mainThread())
//                                        .subscribe(newDevice -> {
//                                                       Log.i("DeviceUpgradeManager","【OTA - 检查更新】DeviceUpgradeManager=reset=ConnectDevice ==" + newDevice);
//                                            DeviceConnectManager.setConnectDevice(newDevice);
//                                        }, error -> {
//                                                       Log.i("DeviceUpgradeManager","【OTA - 检查更新】reset ConnectDevice error");
//                                        });
//                            }
//
//
//                    } else {
//                                   Log.i("DeviceUpgradeManager","【OTA - 检查更新】设备未连接");
//                    }
//                } finally {
//                               Log.i("DeviceUpgradeManager","【OTA - 检查更新】载入缓存数据...");
//                }
//                emitter.onComplete();
//            } catch (Exception e) {
//                           Log.i("DeviceUpgradeManager","【OTA - 检查更新】失败", e);
//                emitter.onError(e);
//            } finally {
//                           Log.i("DeviceUpgradeManager","【OTA - 检查更新】结束");
//            }
//        }).subscribeOn(Schedulers.io());
//    }

    public static Observable<Float> upgrade(File zip1,File zip2) {
        Log.i("DeviceUpgradeManager", "进来了", null);
        return Observable.<Float>create(emitter -> {
            try {
                Log.i("DeviceUpgradeManager", "进来了", null);

                Log.i("DeviceUpgradeManager", "【OTA - 检查更新】...OTA开始，重新请求接口");
                    qjsDownZipState.postValue(true);
                    File directory1 = new File(sApplication.getCacheDir(), "device/qjs");
                        if (!directory1.exists()) {
                            directory1.mkdirs();
                        }

                    directory1.mkdirs();

                    ArrayList<String> urls = unzip(zip1.getPath(), directory1.getPath());
                Log.i("DeviceUpgradeManager", "【OTA - 更新】==== "+zip1.getAbsolutePath()+" === ", null);
                Log.i("DeviceUpgradeManager", "【OTA - 更新】==== "+directory1.getPath()+" === ", null);
                    qjsDownZipState.postValue(false);
                    Log.i("DeviceUpgradeManager", "【OTA - 更新】==== 下载解压zip完成; === ", null);
                    ArrayList<DFUImagePath> dfuImagePaths = new ArrayList<>();
                    DFUImagePath ctrlPath = null;
                    DFUImagePath diffCtrlpath = null;
                    DFUImagePath hcpuPath = null;
                    DFUImagePath lcpuPath = null;
                    DFUImagePath patchPath = null;
                    DFUImagePath outdynPath = null;
                    DFUImagePath outrootPath = null;
                    File file;
                Log.i("DeviceUpgradeManager", "【OTA - 更新】==== "+urls.size()+" === ", null);
                    for (int i = 0; i < urls.size(); i++) {
                        Log.i("DeviceUpgradeManager", "【OTA - 更新】==== "+urls+" === ", null);
                        String fileUrl = urls.get(i);
                        file = new File(fileUrl);
                        String fileName = file.getName();
                        /**
                         * 1: ctrl判断是否全部更新。2.1 diff_ctrl判断差分,是的话，resource的url文件更新
                         * 2.2 更新这三个hcpu patch_lcpu lcpu
                         */
                        if (fileName.startsWith("ctrl") && fileName.endsWith(".bin")) {
                            ctrlPath = new DFUImagePath(fileUrl, null, IMAGE_ID_CTRL);
//                                dfuImagePaths.add(ctrlPath);
                        }

                        if (fileName.startsWith("diff_ctrl") && fileName.endsWith(".bin")) {
                            diffCtrlpath = new DFUImagePath(fileUrl, null, IMAGE_ID_CTRL);
//                                dfuImagePaths.add(diffCtrlpath);
                        }

                        if (fileName.startsWith("hcpu") && fileName.endsWith(".bin")) {
                            hcpuPath = new DFUImagePath(fileUrl, null, IMAGE_ID_HCPU);
                            dfuImagePaths.add(hcpuPath);
                        }
                        if (fileName.startsWith("lcpu") && fileName.endsWith(".bin")) {
                            lcpuPath = new DFUImagePath(fileUrl, null, IMAGE_ID_LCPU);
                            dfuImagePaths.add(lcpuPath);
                        }
                        if (fileName.startsWith("patch") && fileName.endsWith(".bin")) {
                            patchPath = new DFUImagePath(fileUrl, null, IMAGE_ID_NAND_LCPU_PATCH);
                            dfuImagePaths.add(patchPath);
                        }
                        if (fileName.startsWith("outdyn") && fileName.endsWith(".bin")) {
                            outdynPath = new DFUImagePath(fileUrl, null, IMAGE_ID_DYN);
//                                dfuImagePaths.add(outdynPath);
                        }
                        if (fileName.startsWith("outroot") && fileName.endsWith(".bin")) {
                            outrootPath = new DFUImagePath(fileUrl, null, IMAGE_ID_RES);
//                                dfuImagePaths.add(outrootPath);
                        }
                    }
                    Log.i("DeviceUpgradeManager", "【OTA - 更新】判断OTA哪种模式更新开始", null);
                    //优先拆分
                    if (diffCtrlpath != null) {
                        dfuImagePaths.add(diffCtrlpath);
                        Log.i("DeviceUpgradeManager", "【OTA - 更新】OTA业务逻辑开始===diffCtrlpath != null==差分", null);
                            Log.i("DeviceUpgradeManager", "【OTA - 更新】OTA业务逻辑开始===diffCtrlpath != 下载resource==", null);
                            dfuImagePaths.add(new DFUImagePath(zip2.getPath(), null, IMAGE_ID_NAND_RES));

                        Log.i("DeviceUpgradeManager", "【OTA - 更新】OTA业务逻辑开始=== start ===startActionDFUNand", null);
                        emitter.onComplete();
                        //进入sdk更新之后才会有失败后的自动更新
                        Log.i("DeviceUpgradeManager", "【OTA - 更新】=====SM.spSaveBoolean===true", null);
                        for (int i = 0; i < dfuImagePaths.size(); i++) {
                            Log.i("DeviceUpgradeManager", "【OTA - 更新】==file==" + dfuImagePaths.get(i).getImagePath(), null);
                        }
                        SifliDFUService.startActionDFUNand(sApplication, SM.spLoadStringno(sApplication, "MAC"), dfuImagePaths, DFU_MODE_NORMAL, 0);

                    } else {


                    }

            } catch (Exception e) {
                Log.i("DeviceUpgradeManager", "【OTA - 更新】失败", e);
                emitter.onError(e);
            }
        }).doOnComplete(() -> {
            Log.i("DeviceUpgradeManager", "【OTA - 更新】结束");
        }).subscribeOn(Schedulers.io());
    }

    private static ArrayList<String> readQJSOtaData(DeviceUpgradeInfo.Firmware firmware, UploadFileUtils.ProgressListener listener) {
        Log.i("DeviceUpgradeManager", "【QJS - OTA - 读取更新包】开始读取更新包：url = " + firmware.url + ", md5 = " + firmware.md5);
        File directory = new File(sApplication.getCacheDir(), "device/qjs");
        File file = new File(directory, firmware.md5);
        Single<ByteBuffer> byteBuffersingle = UploadFileUtils.downloadFile(UploadFileUtils.parsePath(firmware.url),listener);
        byte[] dataBytes = byteBuffersingle.blockingGet().array();
//        byte[] dataBytes = UploadFileUtils.downloadFile(UploadFileUtils.parsePath(firmware.url)).blockingGet().array();
        String dataBytesDigest = MD5Utils.getMD5(dataBytes);
        Log.i("DeviceUpgradeManager", "【QJS - OTA - 读取更新包】文件下载完成：Size = " + dataBytes.length + ", MD5 = " + dataBytesDigest);
        if (!dataBytesDigest.equalsIgnoreCase(firmware.md5)) {
            Log.i("DeviceUpgradeManager", "【QJS - OTA - 读取更新包】数据检验未通过");
//            throw new IllegalStateException("Invalid Data");
        }
        directory.mkdirs();
        FilesKt.writeBytes(file, dataBytes);

        String zipFilePath = file.getPath();
        String destDir = directory.getPath();
        return unzip(zipFilePath, destDir);
    }

    public static ArrayList<String> unzip(String zipFilePath, String destDir) {
        ArrayList<String> files = new ArrayList();
        try {
            File dir = new File(destDir);
            if (!dir.exists()) dir.mkdirs();
            FileInputStream fis = new FileInputStream(zipFilePath);
            ZipInputStream zis = new ZipInputStream(fis);
            byte[] buffer = new byte[1024];
            ZipEntry zipEntry = zis.getNextEntry();
            while (zipEntry != null) {
                String fileName = zipEntry.getName();
                File newFile = new File(destDir + File.separator + fileName);
                if (zipEntry.isDirectory()) {
                    newFile.mkdirs();
                } else {
                    if(!newFile.getParentFile().exists()){
                        newFile.getParentFile().mkdirs();
                    }
                    FileOutputStream fos = new FileOutputStream(newFile);
                    int len;
                    while ((len = zis.read(buffer)) > 0) {
                        fos.write(buffer, 0, len);
                    }
                    fos.close();
                    files.add(newFile.getAbsolutePath());
                }
                zipEntry = zis.getNextEntry();
            }
            zis.closeEntry();
            zis.close();
            fis.close();
        } catch (Exception e) {
            Log.i("DeviceUpgradeManager", "【QJS - OTA - unzip--catch"+ e.toString());
        }
        return files;
    }

//    public static boolean canUpgrade(String currentFirmwareVersion, Long currentBuildCode, String destFirmwareVersion, Long destBuildCode) {
//        try {
//            if (Objects.equals(currentFirmwareVersion, destFirmwareVersion)) {
//                return currentBuildCode < destBuildCode;
//            }
//            String[] currentFirmwareVersionSnippets = currentFirmwareVersion.split("\\.");
//            String[] destFirmwareVersionSnippets = destFirmwareVersion.split("\\.");
//            if (currentFirmwareVersionSnippets.length != destFirmwareVersionSnippets.length)
//                return false;
//            for (int i = 0; i < currentFirmwareVersionSnippets.length; i++) {
//                if (Objects.equals(currentFirmwareVersionSnippets[i], destFirmwareVersionSnippets[i])) {
//                    continue;
//                }
//                return Integer.parseInt(currentFirmwareVersionSnippets[i]) < Integer.parseInt(destFirmwareVersionSnippets[i]);
//            }
////            throw new IllegalStateException("[" + currentFirmwareVersion + "," + currentBuildCode + "," + destFirmwareVersion + "," + destBuildCode + "]");
//        } catch (Exception e) {
//            Log.i("DeviceUpgradeManager", "【OTA - 版本比较】异常", e);
//            return false;
//        }
//    }

    private static byte[] readOtaData(String url, String md5) {
        Log.i("DeviceUpgradeManager", "【OTA - 读取更新包】开始读取更新包：url = " + url + ", md5 = " + md5);
        File directory = new File(sApplication.getCacheDir(), "device/firmwares");
        File file = new File(directory, md5);
        if (file.exists()) {
            byte[] bytes = FilesKt.readBytes(file);
            Log.i("DeviceUpgradeManager", "【OTA - 读取更新包】缓存文件可用：[Size = " + bytes.length + "]" + file);
            return bytes;
        } else {
            byte[] dataBytes = UploadFileUtils.downloadFile(UploadFileUtils.parsePath(url)).blockingGet().array();
            String dataBytesDigest = MD5Utils.getMD5(dataBytes);
            Log.i("DeviceUpgradeManager", "【OTA - 读取更新包】文件下载完成：Size = " + dataBytes.length + ", MD5 = " + dataBytesDigest);
            if (!dataBytesDigest.equalsIgnoreCase(md5)) {
                Log.i("DeviceUpgradeManager", "【OTA - 读取更新包】数据检验未通过");
//                throw new IllegalStateException("Invalid Data");
            }
            directory.mkdirs();
            FilesKt.writeBytes(file, dataBytes);
            Log.i("DeviceUpgradeManager", "【OTA - 读取更新包】数据缓存成功：[Size = " + file.length() + "]" + file);
            return dataBytes;
        }
    }




}